package gis.toolkit;

import bean.common.Cell;
import bean.ltecover.BuildingEx;
import gis.algorithm.GeoPoint;
import gis.algorithm.GeoUtils;
import gis.algorithm.PointTransform;
import gis.core.utils.CoreUtils;
import gis.core.utils.HttpRequest;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.math.util.MathUtils;
import org.json.JSONArray;
import org.json.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by Xiaobing on 2017/3/25.
 */
public class BaiduHelper {

    private static Logger logger = LoggerFactory.getLogger(BaiduHelper.class);
    private String basePath = this.getClass().getResource("/").getPath();
    static String keywords_url = "http://map.baidu.com/su?cid=58&type=0&pc_ver=2";
    static String path_url = "http://map.baidu.com/?newmap=1&reqflag=pcmap&biz=1&from=webmap&da_par=baidu&pcevaname=pc4.1&qt=ext&ext_ver=new&tn=B_NORMAL_MAP&nn=0&u_loc=&ie=utf-8&l=17&b=&t=";
    static String point_url = "http://api.map.baidu.com/geoconv/v1/?from=6&to=5&ak=1efd377ebdd63f6018cd107f1bdf8816";

    /**
     * @param args
     */
    public static void main(String[] args) {
        BaiduHelper helper = new BaiduHelper();
        helper.getData();

        /*double[] _a = PointTransform.mercator_decrypt(3433489.21699, 11858139.6038);
        double[] a = PointTransform.bd_decrypt(29.620028240258, 106.52232140972);
        double[] b = PointTransform.gcj_decrypt(a[0], a[1]);*/
    }

    public void getData() {
        System.out.println("开始读取小区数据。。。");
        List<Cell> cells = getDemoCell();//getCell();

        List<BuildingEx> buildingExes = new ArrayList<>();
        JSONObject cellObject = null;
        List<String> ring_baidu_list = new ArrayList<>();
        List<String> points_baidu_list = new ArrayList<>();
        int count = 0;

        for (Cell cell : cells) {
            count++;
            if (count % 10 == 0) {
                System.out.println("完成采集数据 " + count + "    完成 " + MathUtils.round((count * 1.0 / cells.size()) * 100, 2) + "%");
            }
            try {

                cellObject = getKeywordsConent(cell.getName());//获取POI  id
                JSONObject temp = cellObject;
                if (temp != null) {
                    Object s = temp.get("s");
                    if (s == null || s.equals(null)) {
                        continue;
                    }
                    JSONArray kpis = temp.getJSONArray("s");
                    for (int j = 0; j < kpis.length(); j++) {
                        String kpi = kpis.getString(j);
                        String[] kpiInfo = StringUtils.splitPreserveAllTokens(kpi + "", "$");

                        if (cell.getName().equals(kpiInfo[3])) {
                            BuildingEx buildingEx = new BuildingEx();
                            buildingEx.setType(0);
                            buildingEx.setId(kpiInfo[5]);
                            buildingEx.setName(kpiInfo[3]);
                            buildingEx.setCityName(kpiInfo[0]);

                            ring_baidu_list.clear();
                            String ring_paht = path_url + "&uid=" + kpiInfo[5] + "&c=" + kpiInfo[4];//取边界数据
                            String json_ring_Str = HttpRequest.sendGet(ring_paht, null);
                            JSONObject ring_object = new JSONObject(json_ring_Str);
                            if (ring_object == null) continue;
                            String ring_contnet_geo = ring_object.getJSONObject("content").getString("geo");//取边疆数据
                            String[] ring_conent_geo_arr = StringUtils.splitPreserveAllTokens(ring_contnet_geo, "-");

                            //有边界的数据
                            if (ring_conent_geo_arr.length == 2) {
                                //边疆数据坐标系转换  百度墨卡多---》百度经纬度
                                String[] ring_baidu_arr = StringUtils.splitPreserveAllTokens(ring_conent_geo_arr[1].replace(";", ""), ",");
                                for (int i = 0; i < ring_baidu_arr.length; i = i + 2) {
                                    if (i + 1 >= ring_baidu_arr.length) break;
                                    ring_baidu_list.add(ring_baidu_arr[i] + "," + ring_baidu_arr[i + 1]);
                                    if (ring_baidu_list.size() == 90) {
                                        points_baidu_list.add(StringUtils.join(ring_baidu_list, ";"));
                                        ring_baidu_list.clear();
                                    }
                                }
                                if (ring_baidu_list.size() > 0) {
                                    points_baidu_list.add(StringUtils.join(ring_baidu_list, ";"));
                                    ring_baidu_list.clear();
                                }
                                for (String points_baidu : points_baidu_list) {
                                    List<GeoPoint> points = getBaiduPoint(points_baidu);
                                    buildingEx.getRing().addAll(points);
                                }
                                ring_baidu_list.clear();
                                points_baidu_list.clear();


                                buildingEx.setExtent(GeoUtils.getExtent(buildingEx.getRing()));
                                buildingEx.setCenter(buildingEx.getExtent().getCenter());
                                buildingExes.add(buildingEx);
                                if (buildingExes.size() > 10) {
                                    outGaodeComm(buildingExes);
                                    buildingExes.clear();
                                }
                            }
                            //有边界的数据
                            else if (cell.getCityName().equals(buildingEx.getCityName())) {
                            }
                        }
                    }
                }

            } catch (Exception e) {
                System.out.println("！！！！！！！完成采集数据异常： " + e.getMessage());
                continue;
            }


        }
        outGaodeComm(buildingExes);

    }

    private JSONObject getKeywordsConent(String name) throws UnsupportedEncodingException {
        String path = keywords_url + "&wd=" + URLEncoder.encode(name, "utf-8");
        String jsonStr = HttpRequest.sendGet(path, null);
        JSONObject httpJson = new JSONObject(jsonStr);
        return httpJson;
    }

    /**
     * 从百度墨卡托-->百度经纬度
     *
     * @param points
     * @return
     */
    private List<GeoPoint> getBaiduPoint(String points) {
        List<GeoPoint> list = new ArrayList<>();
        String points_baiud_url = point_url + "&coords=" + points;
        String points_list = HttpRequest.sendGet(points_baiud_url, null);
        JSONObject points_list_object = new JSONObject(points_list);
        if (points_list_object.get("status").equals(0)) {
            JSONArray pointJsonArray = points_list_object.getJSONArray("result");
            for (int m = 0; m < pointJsonArray.length(); m++) {
                JSONObject pointJson = pointJsonArray.optJSONObject(m);
                double[] yx = PointTransform.bd_gcj_decrypt(pointJson.getDouble("y"), pointJson.getDouble("x"));
                list.add(new GeoPoint(yx[1], yx[0]));
            }
        }
        return list;
    }

    private List<Cell> getCell() {
        List<Cell> list = new ArrayList<>();
        String filePath = basePath + "t_mapbarpoi_info.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        Cell cell = null;
        int count = 0;
        String[] datas;
        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            String line = null;

            while ((line = reader.readLine()) != null) {
                count++;
                if (StringUtils.isEmpty(line) || count == 1) {
                    continue;
                }
                // 文本中第一个字符为特殊字符
                if ((int) line.charAt(0) == 65279) {
                    line = line.substring(1);
                }

                datas = StringUtils.splitPreserveAllTokens(line, ",");
                cell = new Cell();
                cell.setCell_order_id(count - 1);
                cell.setTag(datas[1]);
                cell.setId(datas[2]);
                cell.setName(datas[3]);
                cell.setCityName(datas[0]);
                list.add(cell);
            }

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            CoreUtils.close(reader, stream);
        }

        return list;
    }


    private List<Cell> getDemoCell() {
        List<Cell> list = new ArrayList<>();
        String filePath = basePath + "demo.txt";
        InputStreamReader stream = null;
        BufferedReader reader = null;
        Cell cell = null;
        int count = 0;
        String[] datas;
        try {
            stream = new InputStreamReader(new FileInputStream(filePath), "UTF-8");
            reader = new BufferedReader(stream);
            String line = null;

            while ((line = reader.readLine()) != null) {
                count++;
                if (StringUtils.isEmpty(line) || count == 1) {
                    continue;
                }
                // 文本中第一个字符为特殊字符
                if ((int) line.charAt(0) == 65279) {
                    line = line.substring(1);
                }

                datas = StringUtils.splitPreserveAllTokens(line, ",");
                cell = new Cell();
                cell.setCell_order_id(count - 1);
                cell.setName(datas[0]);
                /*cell.setTag(datas[1]);
                cell.setId(datas[2]);
                cell.setName(datas[3]);
                cell.setCityName(datas[0]);*/
                list.add(cell);
            }

        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        } finally {
            CoreUtils.close(reader, stream);
        }

        return list;
    }

    private void outGaodeComm(List<BuildingEx> list) {
        //开始写入文件
        int f = 0;
        String path = basePath + "demo_ok.txt";
        File file = new File(path);
        boolean isTitle = false;
        if (!file.exists()) {
            isTitle = true;
        }

        FileOutputStream out = null;
        OutputStreamWriter osw = null;
        BufferedWriter bw = null;
        try {
            out = new FileOutputStream(file, true);
            osw = new OutputStreamWriter(out, "UTF-8");
            bw = new BufferedWriter(osw);
            if (isTitle) {
                //标题
                bw.append("type|id|name|cityName|address|xmax|ymax|xmin|ymin|centerx|centery|ring\n");
                isTitle = false;
            }
            for (f = 0; f < list.size(); f++) {
                StringBuffer sb = new StringBuffer();
                BuildingEx b = list.get(f);
                if (b.getRing().size() == 0) {
                    //continue;
                }

                sb.append(b.getType() + "|" + b.getId() + "|" + b.getName() + "|" + b.getCityName() + "|" + b.getAddress());
                sb.append("|" + b.getExtent().getxMax() + "|" + b.getExtent().getyMax() + "|" + b.getExtent().getxMin() + "|" + b.getExtent().getyMin());

                GeoPoint center = b.getCenter();
                if (center == null) {
                    center = GeoUtils.getGravityCenter(b.getRing());
                }
                sb.append("|" + center.getX() + "|" + center.getY());
                sb.append("|" + StringUtils.join(b.getRing().toArray(), ","));
                sb.append("\n");
                bw.write(sb.toString());
            }
            bw.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}
